﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace CPPEI.Coolzon.UI.StaticPartLib
{
    /// <summary>
    /// Interaction logic for PartVLoopImage.xaml
    /// </summary>
    [System.ComponentModel.DisplayName("垂直滚动图片")]
    [XPartIcon("pack://application:,,,/CPPEI.Coolzon.UI.StaticPartLib;component/Images/PartIcons/垂直滚动图.png")]
    public partial class PartVLoopImage : ControlPart
    {
        [Category("Appearance")]
        [DisplayName("显示的图片")]
        [Description("Image")]
        [Editor(typeof(UI.XProperty.Editors.XImageSourceFileEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "Image", "显示的图片", false)]
        public ImageSourceFile XImage
        {
            get
            {
                return _XImage;
            }
            set
            {
                _XImage = value;
                Refresh();
            }
        }

        [Category("Appearance")]
        [DisplayName("滚动时间间隔")]
        [Description("LoopInterval")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "LoopInterval", "滚动时间间隔", false)]
        public double XLoopInterval
        {
            get
            {
                return _XLoopInterval;
            }
            set
            {
                _XLoopInterval = value;
                Refresh();
            }
        }

        [Category("Appearance")]
        [DisplayName("一次滚动的距离")]
        [Description("LoopStepLength")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "LoopStepLength", "一次滚动的距离", false)]
        public double XLoopStepLength
        {
            get
            {
                return _XLoopStepLength;
            }
            set
            {
                _XLoopStepLength = value;
                Refresh();
            }
        }
        [Category("Appearance")]
        [DisplayName("一次滚动的时间")]
        [Description("LoopDuration")]
        [Editor(typeof(UI.XProperty.Editors.XDoubleEditor), typeof(UI.XProperty.XPropertyValueEditor))]
        [XProperty(XPropertyCategory.Appearance, "LoopDuration", "一次滚动的时间", false)]
        public double XLoopDuration
        {
            get
            {
                return _XLoopDuration;
            }
            set
            {
                _XLoopDuration = value;
                Refresh();
            }
        }

        /// <summary>
        /// 滚动的偏移值，单次滚动
        /// </summary>
        public double LoopOffset
        {
            get
            {
                return (double)GetValue(LoopOffsetProperty);
            }
            set
            {
                SetValue(LoopOffsetProperty, value);
            }
        }

        public static DependencyProperty LoopOffsetProperty = DependencyProperty.Register("LoopOffset",
            typeof(double),
            typeof(PartVLoopImage),
            new PropertyMetadata(default(double), OnLoopOffsetPropertyChangedCallback));
        
        public static void OnLoopOffsetPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PartVLoopImage image = d as PartVLoopImage;
            if (image.IsActived)
            {
                double dNewValue = (double)e.NewValue;
                double dOldValue = (double)e.OldValue;
                double deltaOffset = 0;
                if (dNewValue > dOldValue)
                {
                    deltaOffset = dNewValue - dOldValue;
                }
                else
                {
                    deltaOffset = dNewValue + (image.XLoopStepLength - dOldValue);
                }
                image._destLoopOffset += deltaOffset;
                image._destLoopOffset = image._destLoopOffset % image._ctlImage.ActualHeight;

                double offsetImage = -image._destLoopOffset;
                if (offsetImage < -image._ctlImage.ActualHeight)
                {
                    offsetImage = offsetImage + image._ctlImage.ActualHeight;
                }
                double offsetVisual = offsetImage + image._ctlImage.ActualHeight;

                Canvas.SetTop(image._ctlImage, offsetImage);
                Canvas.SetTop(image._ctlVisual, offsetVisual);
                image._ctlVisual.Visibility = Visibility.Visible;
            }
        }

        private Storyboard _loopAnimation;
        private double _destLoopOffset;
        private ImageSourceFile _XImage;
        private double _XLoopInterval;
        private double _XLoopStepLength;
        private double _XLoopDuration;

        public PartVLoopImage()
        {
            InitializeComponent();

            XLoopDuration = 1;
            XLoopInterval = 2;
            XLoopStepLength = 100;

            ClipToBounds = true;
            _ctlVisual.Visibility = System.Windows.Visibility.Hidden;
        }

        protected override void OnInit(PartContext context)
        {
            base.OnInit(context);
        }

        protected override void OnApplyXProperty()
        {
            base.OnApplyXProperty();
            if (XImage != null)
            {
                _ctlImage.Source = XImage.ImageSource;
                _ctlImage.Stretch = Stretch.Fill;
                if (this.XWidth > (XBorderThickness.Left + XBorderThickness.Right + XPadding.Left + XPadding.Right))
                {
                    _ctlImage.Width = _ctlCanvas.Width = this.XWidth - (XBorderThickness.Left + XBorderThickness.Right + XPadding.Left + XPadding.Right);
                }
                else
                {
                    _ctlImage.Width = _ctlCanvas.Width = 0;
                }
                if(this.XHeight > (XBorderThickness.Top + XBorderThickness.Bottom + XPadding.Top + XPadding.Bottom))
                {
                    _ctlImage.Height = _ctlCanvas.Height = this.XHeight - (XBorderThickness.Top + XBorderThickness.Bottom + XPadding.Top + XPadding.Bottom);
                }
                else
                {
                    _ctlImage.Height = _ctlCanvas.Height = 0;
                }
                _ctlCanvas.ClipToBounds = true;


                if (_loopAnimation != null)
                {
                    _loopAnimation.Stop();
                    _loopAnimation.Remove();
                    _loopAnimation = null;
                }

                _destLoopOffset = 0;
                this.LoopOffset = 0;

                double waitTime = XLoopInterval - XLoopDuration;
                if (waitTime < 0)
                {
                    waitTime = 0;
                }

                _loopAnimation = new Storyboard();
                // 重复播放
                _loopAnimation.RepeatBehavior = RepeatBehavior.Forever;
                _loopAnimation.AutoReverse = false;
                DoubleAnimation animation = new DoubleAnimation(0, XLoopStepLength, TimeSpan.FromSeconds(XLoopDuration));
                animation.BeginTime = TimeSpan.FromSeconds(waitTime);
                Storyboard.SetTarget(animation, this);
                Storyboard.SetTargetProperty(animation, new PropertyPath(PartVLoopImage.LoopOffsetProperty));
                _loopAnimation.Children.Add(animation);
                _loopAnimation.Begin();
            }
            else
            {
                _ctlImage.Source = null;
                if (_loopAnimation != null)
                {
                    _loopAnimation.Stop();
                    _loopAnimation.Remove();
                    _loopAnimation = null;
                }
            }
        }
        protected override void OnActive(PartContext context)
        {
            if (_loopAnimation != null)
            {
                _loopAnimation.Stop();
                _loopAnimation.Remove();
                _loopAnimation = null;
            }

            _destLoopOffset = 0;
            this.LoopOffset = 0;

            double waitTime = XLoopInterval - XLoopDuration;
            if (waitTime < 0)
            {
                waitTime = 0;
            }

            _loopAnimation = new Storyboard();
            // 重复播放
            _loopAnimation.RepeatBehavior = RepeatBehavior.Forever;
            _loopAnimation.AutoReverse = false;
            DoubleAnimation animation = new DoubleAnimation(0, XLoopStepLength, TimeSpan.FromSeconds(XLoopDuration));
            animation.BeginTime = TimeSpan.FromSeconds(waitTime);
            Storyboard.SetTarget(animation, this);
            Storyboard.SetTargetProperty(animation, new PropertyPath(PartVLoopImage.LoopOffsetProperty));
            _loopAnimation.Children.Add(animation);
            _loopAnimation.Begin();

            base.OnActive(context);

            OnApplyXProperty();
        }

        protected override void OnDeactive(PartContext context)
        {
            if (_loopAnimation != null)
            {
                _loopAnimation.Stop();
                _loopAnimation.Remove();
                _loopAnimation = null;
            }
            base.OnDeactive(context);
        }

        protected override void OnDestory()
        {
            if (_loopAnimation != null)
            {
                _loopAnimation.Stop();
                _loopAnimation.Remove();
                _loopAnimation = null;
            }
            base.OnDestory();
        }
    }
}
